package cn.tedu._07weibo.base.interceptors;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class RateLimitInterceptor implements HandlerInterceptor {
    //访问次数阈值，时间窗口大小
    private static final int MAX_REQUEST_COUNT= 3;
    private static final int MAX_REQUEST_WINDOW_SIZE=60;

    //记录访问次数
    private final ConcurrentHashMap<String,Integer> clientCounts =new ConcurrentHashMap<>();

    //记录访问时间
    private final ConcurrentHashMap<String, LocalDateTime> lastResetTimes =new ConcurrentHashMap<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       log.debug("进入网站限流拦截器...");
       String clientIp =request.getRemoteAddr();//获取客户端IP
       LocalDateTime lastTime= lastResetTimes.get(clientIp);
        /**
         *    1.该IP第一次访问,lastTime为null: 在两个HashMap中添加数据[计数器清零,时间为当前时间];
         *    2.该IP距离最后一次访问超过了60秒:  在两个HashMap中更新数据[计数器清零,时间为当前时间];
         *    3.该IP距离最后一次访问不超过60秒:  计数器+1,时间不变,再和3比较;
         */
        if (lastTime==null || LocalDateTime.now().isAfter(lastTime.plusSeconds(MAX_REQUEST_WINDOW_SIZE))){
            clientCounts.put(clientIp,0);//计时器清零
            lastResetTimes.put(clientIp,LocalDateTime.now()); //时间更新
        }

        Integer i=clientCounts.get(clientIp);
        i=i+1;
        clientCounts.put(clientIp,i);

        if (i>MAX_REQUEST_COUNT){
            throw new RuntimeException("访问过于频繁，请稍后再试...");
        }

        return true;





    }
}
